package com.koron.car.web.authorized.service.impl;

import com.koron.car.config.Constants;
import com.koron.car.web.authorized.bean.entity.DelimitChange;
import com.koron.car.web.authorized.mapper.DelimitChangeMapper;
import com.koron.car.web.authorized.service.DelimitChangeService;
import com.koron.car.web.common.CommonUtils;
import com.koron.common.core.util.CodeTools;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.koron.ebs.mybatis.TaskAnnotation;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class DelimitChangeServiceImpl implements DelimitChangeService {

    @Override
    @TaskAnnotation("getDelimitNum")
    public DelimitChange getDelimitNum(SessionFactory factory, String applyId, String type) {
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        List<DelimitChange> delimits = mapper.queryByApplyId(applyId, type);
        DelimitChange change = new DelimitChange();
        String delimitNum = "";
        if(CollectionUtils.isEmpty(delimits)) {
            delimitNum = Constants.PrepareType.typeMap.get(type) + "001";
        }
        List<Integer> prepareNumber = delimits.stream().map(row -> StringUtils.substring(row.getDelimitNum(), 2)).map(row -> Integer.parseInt(row)).collect(Collectors.toList());
        for (int i = 1; i <= 1000; i++) {
            if(!prepareNumber.contains(i)) {
                delimitNum = Constants.PrepareType.typeMap.get(type) + String.format("%03d", i);
                break;
            }
        }
        Assert.hasText(delimitNum, "编制号已用完");
        change.setDelimitNum(delimitNum);
        change.setDelimitType(type);
        change.setApplyId(applyId);
        insert(factory, change);
        return change;
    }

    @Override
    @TaskAnnotation("queryById")
    public DelimitChange queryById(SessionFactory factory, String changeId) {
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        return mapper.queryById(changeId);
    }

    @Override
    @TaskAnnotation("insertBatch")
    public int insertBatch(SessionFactory factory, List<DelimitChange> changes) {
        if(CollectionUtils.isEmpty(changes)) {
            return 0;
        }
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        CommonUtils.sorted(changes);
        changes.stream().forEach(row -> row.setId(CodeTools.getCode32()));
        return mapper.insertBatch(changes);
    }

    @Override
    @TaskAnnotation("insert")
    public int insert(SessionFactory factory, DelimitChange change) {
        Assert.hasText(change.getApplyId(), "定编申请id不能为空");
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        List<DelimitChange> changes = mapper.queryByApplyId(change.getApplyId(), null);
        Integer sort = CollectionUtils.isEmpty(changes) ? 0 : changes.stream().mapToInt(DelimitChange::getSort).max().getAsInt();
        change.setSort(sort + 1);
        change.setId(StringUtils.isBlank(change.getId()) ? CodeTools.getCode32() : change.getId());
        return mapper.insert(change);
    }

    @Override
    @TaskAnnotation("deleteById")
    public boolean deleteById(SessionFactory factory, String changeId) {
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        return mapper.deleteById(changeId) > 0;
    }

    @Override
    @TaskAnnotation("deleteByApplyId")
    public boolean deleteByApplyId(SessionFactory factory, String applyId) {
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        return mapper.deleteByApplyId(applyId) > 0;
    }

    @Override
    @TaskAnnotation("queryByApplyId")
    public List<DelimitChange> queryByApplyId(SessionFactory factory, String applyId) {
        DelimitChangeMapper mapper = factory.getMapper(DelimitChangeMapper.class);
        return mapper.queryByApplyId(applyId, null);
    }
}
